import com.firenio.Options;
import com.firenio.codec.http11.HttpCodec;
import com.firenio.codec.http11.HttpConnection;
import com.firenio.codec.http11.HttpContentType;
import com.firenio.codec.http11.HttpDateUtil;
import com.firenio.codec.http11.HttpFrame;
import com.firenio.collection.ByteTree;
import com.firenio.common.Unsafe;
import com.firenio.component.Channel;
import com.firenio.component.ChannelAcceptor;
import com.firenio.component.ChannelEventListenerAdapter;
import com.firenio.component.Frame;
import com.firenio.component.IoEventHandle;
import com.firenio.component.NioEventLoopGroup;
import com.firenio.component.SocketOptions;
import com.firenio.log.LoggerFactory;

public class BenchFire {
	private static final int PORT = Integer.getInteger("port", 10000);
	private static final byte[] text = "Hello, World!".getBytes();
	private static final HttpContentType ct = HttpContentType.add("text/plain; charset=UTF-8");

	public static void main(String[] args) throws Exception {
		LoggerFactory.setEnableSLF4JLogger(false);
		LoggerFactory.setLogLevel(LoggerFactory.LEVEL_INFO);
		Options.setBufAutoExpansion(false);
		Options.setChannelReadFirst(false);
		Options.setEnableEpoll(Boolean.getBoolean("epoll"));
		Options.setEnableUnsafeBuf(Unsafe.UNSAFE_AVAILABLE);

		HttpDateUtil.start();
		NioEventLoopGroup group = new NioEventLoopGroup();
		group.setEnableMemoryPool(Boolean.getBoolean("pool"));
		group.setMemoryCapacity(Integer.getInteger("memCap", 0));
		group.setMemoryUnit(Integer.getInteger("memUnit", 512));
		group.setWriteBuffers(Integer.getInteger("writeBuf", 32));
		group.setChannelReadBuffer(Integer.getInteger("readBuf", 1024 * 512));
		group.setEventLoopSize(Integer.getInteger("thread", 1));
		group.setConcurrentFrameStack(Boolean.getBoolean("concFrameStack"));
		ChannelAcceptor context = new ChannelAcceptor(group, PORT);
		context.addChannelEventListener(new ChannelEventListenerAdapter() {
			@Override
			public void channelOpened(Channel ch) throws Exception {
				ch.setOption(SocketOptions.TCP_NODELAY, 1);
				ch.setOption(SocketOptions.SO_KEEPALIVE, 0);
			}
		});
		ByteTree cachedUrls = new ByteTree();
		cachedUrls.add("/plaintext");
		context.addProtocolCodec(new HttpCodec("fire0", Integer.getInteger("frameCache", 1024 * 16), true, cachedUrls));
		context.setIoEventHandle(new IoEventHandle() {
			@Override
			public void accept(Channel ch, Frame frame) throws Exception {
				HttpFrame f = (HttpFrame)frame;
				String action = f.getRequestURL();
				if ("/plaintext".equals(action)) {
					f.setContent(text);
					f.setContentType(ct);
					f.setConnection(HttpConnection.NONE);
				}
				f.setDate(HttpDateUtil.getDateLine());
				ch.writeAndFlush(f);
				ch.release(f);
			}
		});
		context.bind(1024 * 8);
	}
}
